import os
import sys
from typing import List

# 将工程目录加入包扫描
currPath = os.path.abspath(os.path.dirname(__file__))
srcPath = os.path.split(currPath)[0]
rootPath = os.path.split(srcPath)[0]
projectPath = os.path.split(rootPath)[0]
sys.path.append(projectPath)

from src.tasks.enterpriseToEs.EntEnterprise import EntEnterprise
from src.utils import CommonUtils, BatchUtils
from src.utils.CommonUtils import getProperty


class SyncEnterpriseBaseInfo:
    def __init__(self, logger, localDb, dataCenterDb, fcdb, useCache=False):
        self.logger = logger
        self.localDb = localDb
        self.dataCenterDb = dataCenterDb
        self.fcdb = fcdb
        self.size = 1000
        self.useCache = useCache
        self.cityInvestmentDatas = {}
        self.regions = {}
        self.modelMap = {"T001": "产业企业", "T002": "城投企业", "T003": "商业银行", "T004": "证券公司", "T006": "担保公司"}
        self.hy015Map = {}
        self.hy012Map = {}
        self.hy040Map = {}
        self.bankLevelMap = {}
        self.modelIndustryMapping = []
        self.adminLevelMap = {1: "省级", 2: "地市级", 3: "区县级", 4: "功能区-省级", 5: "功能区-地市级", 6: "功能区-区县级"}
        self.natureMap = {"001001": 1, "001002": 2, "001003": 3, "001004": 4, "001005": 5, "001006": 9,
                          "002001": 6, "003001": 7, "99": 9, "001007": 8, "001008": 9, "001009": 9}

    # 抽取待更新主体名单，classify_type = 0
    def __queryLocal__(self):
        sql = "select id, credit_code, comp_code, ent_type from ent_enterprise where classify_type=0"
        return self.localDb.Query(sql)
        # 抽取基础数据

    # 查询城投所属区域代码
    def __queryCityInvestmentData__(self):
        sql = """ SELECT c.credit_code,
                     max(case when d.second_code = 'CTJC002001' then  d.value ELSE null END ) 'CTJC002001',
                     max(case when d.second_code = 'CTJC002003' then  d.value ELSE null END) 'CTJC002003' ,
                     max(case when d.second_code = 'CTJC002005' then  d.value ELSE null END ) 'CTJC002005'
                     FROM city_investment_companies c
                     inner JOIN city_investment_companies_data_detail d ON c.id = d.foreign_id
                     INNER JOIN enterprise_info_custom ic ON ic.credit_code = c.credit_code
                     WHERE c.ver=0 AND c.release_status=1 AND c.`status`=1 
                     AND d.second_code IN ('CTJC002001','CTJC002003','CTJC002005')
                     AND ic.type_code='T002' AND ic.ver=0 AND ic.release_status =1 AND ic.audit_status = 1
                     GROUP BY c.credit_code
            """
        return self.dataCenterDb.Query(sql)

    # 缓存所有区域代码
    def __queryRegions__(self):
        sql = " SELECT * from regions WHERE ver=0 AND release_status=1"
        return self.dataCenterDb.Query(sql)

    # 加载医药二级行业
    def __queryHY015Mapping__(self):
        sql = """
                WITH yy00010 AS (
                    SELECT credit_code, `year`,`value`
                    FROM (
                    SELECT a.credit_code, a.`year`, d.`value`,ROW_NUMBER() OVER (PARTITION BY a.credit_code
                    ORDER BY a.year DESC) AS NO
                    FROM pharmaceutical_annual_data a
                    INNER JOIN pharmaceutical_annual_data_detail d ON a.id = d.foreign_id
                    INNER JOIN enterprise_info_custom c ON c.credit_code = a.credit_code
                    WHERE a.ver = 0 AND a.`status` = 1 AND a.release_status = 1 AND d.code='YY00010' AND c.score_type = 'HY015'
                    ) t WHERE t.`no` = 1
                )
                SELECT * FROM yy00010 
        """
        return self.dataCenterDb.Query(sql)

    # 加载农林牧渔二级行业
    def __queryHY012Mapping__(self):
        sql = """
                WITH NLMY0004 AS (
                    SELECT credit_code, `year`,`value`
                    FROM (
                    SELECT a.credit_code, a.`year`, d.`value`,ROW_NUMBER() OVER (PARTITION BY a.credit_code
                    ORDER BY a.year DESC) AS NO
                    FROM agribusiness_annual_data a
                    INNER JOIN agribusiness_annual_data_detail d ON a.id = d.foreign_id
                    INNER JOIN enterprise_info_custom c ON c.credit_code = a.credit_code
                    WHERE a.ver = 0 AND a.`status` = 1 AND a.release_status = 1 AND d.code='NLMY0004' AND c.score_type = 'HY012'
                    ) t WHERE t.`no` = 1
                )
                SELECT * FROM NLMY0004 
        """
        return self.dataCenterDb.Query(sql)

    def __queryHY040Mapping__(self):
        sql = """
                WITH RZZL001 AS (
                    SELECT credit_code, `year`,`value`
                    FROM (
                    SELECT a.credit_code, a.`year`, d.`value`,ROW_NUMBER() OVER (PARTITION BY a.credit_code
                    ORDER BY a.year DESC) AS NO
                    FROM financial_lease_annual_data a
                    INNER JOIN financial_lease_annual_data_detail d ON a.id = d.foreign_id
                    INNER JOIN enterprise_info_custom c ON c.credit_code = a.credit_code
                    WHERE a.ver = 0 AND a.`status` = 1 AND a.release_status = 1 AND d.code='RZZL001' AND c.score_type = 'HY040'
                    ) t WHERE t.`no` = 1
                )
                SELECT * FROM RZZL001 
        """
        return self.dataCenterDb.Query(sql)

    # 加载商业银行等级
    def __queryBankLevelMapping__(self):
        sql = """
                SELECT code, (case level  when  0 then "商业银行（全国）" when  1 then "商业银行（省级）" when  2 then "商业银行（地市级）" when  3 then "商业银行（区县级）" end) as level  FROM regions WHERE LEVEL <4
        """
        return self.dataCenterDb.Query(sql)

    def __queryAllFromDcDb__(self):
        sql = """SELECT c.credit_code, c.type_code, c.score_type, s.name AS industry_model,q.regist_capi, q.scope
                FROM enterprise_info_custom c
                LEFT JOIN enterprise_info i ON c.credit_code = i.credit_code AND i.delete_flag = 0
                LEFT JOIN enterprise_type_score s ON s.value = c.score_type
                LEFT JOIN qcc_enterprise_info q ON q.credit_code = c.credit_code 
                where ver = 0 AND release_status = 1 AND audit_status = 1 
                """
        return self.dataCenterDb.Query(sql)

    # 从财汇抽取数据
    def __queryFromFcdb__(self, compCodes):
        sql = """select c.COMPCODE, c.COMPTYPE1,c.COMPTYPE2,c.ORGTYPE, 
                i1.LEVEL1CODE AS SRM_L1_CODE, i1.LEVEL2CODE as SRM_L2_CODE, 
                i2.LEVEL1CODE AS SW_L1_CODE, i2.LEVEL2CODE AS SW_L2_CODE,
                c.REGION,c.ORGTYPE,c.REGCAPITAL,c.FOUNDDATE,c.REGADDR,c.BIZSCOPE
                from TQ_COMP_INFO c
                left join TQ_COMP_INDUSTRY i1 on c.COMPCODE  = i1.COMPCODE  and i1.INDCLASSCODE='2202' AND i1.ENDDATE='19000101'
                left join TQ_COMP_INDUSTRY i2 on c.COMPCODE  = i2.COMPCODE  and i2.INDCLASSCODE='2222' AND i2.ENDDATE='19000101'
                where c.COMPCODE in %s
              """
        return self.fcdb.Query(sql, (compCodes,))

        # 从财汇抽取股东信息

    def __queryShareholder__(self, compCodes):
        sql = """
                  select * from (
                  select ITCODE as COMPCODE, CR0002_003  as SHCOMPNAME, CR0002_006 as PERCENT, 
                  row_number()  over ( partition by ITCODE order by CR0002_004  DESC ) as no
                  from TCR0002_V2_1 where ITCODE in %s  and FLAG  in (0, 2)
                  ) t where t.no = 1
              """
        return self.fcdb.Query(sql, (compCodes,))

    def __queryActualController__(self, compCodes):
        sql = """ 
                  SELECT SITCode, ITNAME_P FROM (
                      SELECT  SITCode, ITNAME_P, ROW_NUMBER() OVER ( PARTITION BY SITCode ORDER BY CR0071_001 DESC  ) AS NO   FROM TCR0071_V2
                      WHERE FLAG IN (0,2) AND SITCode IS NOT null
                      AND SITCode in %s
                      ) t WHERE t.no = 1        
              """
        return self.fcdb.Query(sql, (compCodes,))

    def __writedb__(self, updateDatas):
        sql = """
            REPLACE INTO ent_enterprise
            (id,enterprise_name, credit_code, ent_type, ccx_eval, ccx_eval_date, foreign_external_eval_date, 
            external_eval_date, external_eval, foreign_external_eval, nature, debt_num, debt_scale, trade_type, srm_trade_type, 
            srm_trade_type_superior, sw_trade_type, sw_trade_type_superior, region_code, platform_region_code, 
            administrative_id, work_region_name, ccx_eval_info, external_eval_info, 
            external_eval_organization, foreign_external_eval_info, foreign_external_eval_organization, registered_capital, establishment_date, 
            enterprise_control, share_holder, share_per, `position`, update_time, 
            registered_address, business_scope, classify_type, create_time, comp_code, model, model_level, `year`, model_id, bank_region, ccx_industry_code,
            ccx_eval_value,qe_eval,qe_sort,qe_year)
            VALUES
            (%(id)s,%(enterprise_name)s,%(credit_code)s,%(ent_type)s,%(ccx_eval)s,%(ccx_eval_date)s,
            %(foreign_external_eval_date)s,%(external_eval_date)s,%(external_eval)s,%(foreign_external_eval)s,%(nature)s,%(debt_num)s,%(debt_scale)s,
            %(trade_type)s,%(srm_trade_type)s,%(srm_trade_type_superior)s,%(sw_trade_type)s,%(sw_trade_type_superior)s,%(region_code)s,
            %(platform_region_code)s,%(administrative_id)s,%(work_region_name)s,%(ccx_eval_info)s,
            %(external_eval_info)s,%(external_eval_organization)s,%(foreign_external_eval_info)s,%(foreign_external_eval_organization)s,
            %(registered_capital)s,%(establishment_date)s,%(enterprise_control)s,%(share_holder)s,%(share_per)s,%(position)s,
            %(update_time)s,%(registered_address)s,%(business_scope)s,%(classify_type)s,%(create_time)s,%(comp_code)s,
            %(model)s,%(model_level)s,%(year)s,%(model_id)s,%(bank_region)s,%(ccx_industry_code)s,%(ccx_eval_value)s,
            %(qe_eval)s,%(qe_sort)s,%(qe_year)s)
            """
        return self.localDb.ExecMany(sql, updateDatas)

    def __queryModelIndustryMapping__(self):
        sql = "SELECT * FROM model_industry_mapping"
        return self.localDb.Query(sql)

    def __queryBankDatas__(self):
        sql = "SELECT credit_code,province_id,city_id,country_id,region_id FROM bank_enterprise WHERE ver= 0 AND release_status = 1 AND audit_status = 1"
        return self.dataCenterDb.Query(sql)

    def __convertToEntType__(self, dcData: dict = None, fcdbData: dict = None):
        """
        企业类型规则更新：
            城投企业：以数据中心为准，“企业基础信息”表中，“企业分类”为“城投企业”的，且已发布，一律判断为城投企业；
            产业企业：以数据中心为准，“企业基础信息”表中，“企业分类”为“产业企业”，且“打分卡”存在，且已发布，一律判断为产业企业；
            商业银行：TQ_COMP_INFO表中，COMPTYPE2的值在以下范围则认定“企业类型”为“商业银行”；；
            证券公司：TQ_COMP_INFO表中，COMPTYPE2=E01；
            担保公司：TQ_COMP_INFO表中，COMPTYPE2=Z06；
            其他：除以上类型的其他企业；
        """
        # 根据数据中心数据来判定
        if dcData is not None:
            creditCode = dcData.get("credit_code")
            # 判定是否城投
            if creditCode in self.cityInvestmentDatas.keys():
                return "T002"

            if dcData.get("score_type") is not None:
                # 判定是否是产业
                if dcData.get("type_code") == "T001":
                    return "T001"
                else:
                    # 有打分卡，但不是T001，归类为其他
                    return "T005"

        if fcdbData is not None:
            comptype2 = fcdbData.get("COMPTYPE2")
            # 以CompType2判定
            if comptype2 is not None:
                # 判定是否是商业银行
                if comptype2 in ("C02", "C03", "C04", "C05", "C06", "C07", "C08", "C09", "C10", "C11", "C13", "C14", "C15", "C16", "C99"):
                    return "T003"
                # 判定是否是证券公司
                if comptype2 == "E01":
                    return "T004"
                # 判定是否是担保公司
                if comptype2 == "Z06":
                    return "T006"

    def __convertEnterpriseType__(self, typeCode):
        if typeCode in self.enterpriseType.keys():
            return self.enterpriseType[typeCode]
        return 9

    def __convertNatrue(self, orgType):
        if orgType not in self.natureMap.keys():
            return 9
        return self.natureMap[orgType]

    def __getPosition__(self, creditCode):
        if creditCode not in self.cityInvestmentDatas:
            return None
        return self.cityInvestmentDatas[creditCode]["CTJC002003"]

    def __fillRegions__(self, ent: EntEnterprise):
        """
        拼装城投区域数据
        """
        regionData = None
        cityInvestmentData = None
        # 确定城投所属区域
        if ent.credit_code in self.cityInvestmentDatas.keys():
            cityInvestmentData = self.cityInvestmentDatas[ent.credit_code]
            ent.platform_region_code = cityInvestmentData["CTJC002001"]
            if ent.platform_region_code in self.regions.keys():
                regionData = self.regions[ent.platform_region_code]

        # 确定功能区，处理上级行政区域
        if regionData is not None:
            adminlevel = regionData['fun_parent_administrative_level']
            # 非功能区直接用所在行政区等级，功能区用按照规则采用省市区代码
            if adminlevel is None:
                ent.administrative_id = regionData["code"]
            elif adminlevel == 3:
                ent.administrative_id = regionData["county_code"]
            elif adminlevel == 2:
                ent.administrative_id = regionData["city_code"]
            elif adminlevel == 1:
                ent.administrative_id = regionData["province_code"]

        # 实际作业区域
        ent.work_region_name = cityInvestmentData["CTJC002005"] if cityInvestmentData is not None else None

        return regionData

    def __convertAdminLevel__(self, isFunction, adminLevel):
        if adminLevel is None:
            return None
        if isFunction:
            # 功能区，model_level需要+3
            adminLevel = adminLevel + 3
        if adminLevel in self.adminLevelMap.keys():
            return self.adminLevelMap[adminLevel]
        return None

    def __getModelId__(self, entType, scoreType, regionData):
        for m in self.modelIndustryMapping:
            if entType == "T001":  # 产业
                if m["ent_type"] == entType and m["ccx_model"] == scoreType:
                    return m["model_id"]
            elif entType == "T002":  # 城投
                if regionData["level"] in [1, 2, 3] and regionData["level"] == m["model_level"]:
                    return m["model_id"]
                # 4：国家级新区 5：国家级高新区 6：国家级经开区  7：其他功能区, 上级行政区级别 1,2,3
                # 设定表里,功能区级别 = 上级行政区级别 + 3
                if regionData["level"] in [4, 5, 6, 7] and (regionData["fun_parent_administrative_level"] + 3) == m["model_level"]:
                    return m["model_id"]
            elif m["ent_type"] == entType:  # 其他行业，只需要企业类型一致
                return m["model_id"]

        # 匹配不到任何模型
        return ""

    def __getCcxIndustryCode__(self, entData, dcData):
        entType = entData.ent_type
        if entType == 'T001':
            return self.__getProperty__(dcData, "score_type")
        elif entType == 'T005':
            # 其他 部分企业具有打分卡
            return self.__getProperty__(dcData, "score_type")
        elif entType == "T002":
            return 'HY991'
        elif entType == "T003":
            return 'HY992'
        elif entType == "T004":
            return 'HY993'
        elif entType == "T006":
            return 'HY994'

    def __getTradeType__(self, entData, dcData):
        entType = entData.ent_type
        # 非产业企业，智象行业为固定值
        if entType is not None:
            if entType == "T002":
                return "城投"
            elif entType == "T003":
                return "商业银行"
            elif entType == "T004":
                return "证券公司"
            elif entType == "T006":
                return "担保公司"

        if entType == "T001":
            # 产业企业 智象行业名字部分修正
            tradeType = self.__getProperty__(dcData, "industry_model")
            if tradeType == '交通运输-其他交通运输':
                return '交通运输-其他'
            elif tradeType == '食品饮料':
                return '轻工制造-食品饮料'
            elif tradeType == '轻工制造-其他':
                return '轻工制造-其他制造业'
            else:
                return tradeType

        if entType == "T005":
            scoreType = dcData.get("score_type")
            if scoreType is not None:
                if scoreType == "HY040":
                    return "融资租赁"
                elif scoreType == "HY041":
                    return "人身保险"
                elif scoreType == "HY042":
                    return "财产保险"
                elif scoreType == "HY043":
                    return "资产管理"
                elif scoreType == "HY044":
                    return "消费金融"


    @staticmethod
    def __getProperty__(data, key):
        return getProperty(data, key)

    def __updateDcData__(self, ent: EntEnterprise, dcData: dict):

        if ent.ent_type is None:
            ent.ent_type = self.__convertToEntType__(dcData=dcData)

        # 智象行业
        ent.trade_type = self.__getTradeType__(ent, dcData)

        # 所属区域（仅城投）， 上级行政区（仅功能区），实际作业区域，返回 所属区域数据
        regionData = self.__fillRegions__(ent)

        # 模型
        typeCode = self.__getProperty__(dcData, "type_code")
        if typeCode == "T001":
            ent.model = self.__getProperty__(dcData, "industry_model")
        else:
            if typeCode in self.modelMap.keys():
                ent.model = self.modelMap[typeCode]

        adminlevel = None
        isFunction = False
        if regionData is not None:
            adminlevel = regionData["fun_parent_administrative_level"]
            isFunction = True
            if adminlevel is None:
                adminlevel = regionData["level"]
                isFunction = False

        # 城投模型级别
        if typeCode == "T002":
            ent.model_level = self.__convertAdminLevel__(isFunction, adminlevel)

        # 后台配置的模型UUID
        modelId = self.__getModelId__(ent.ent_type, self.__getProperty__(dcData, "score_type"), regionData)
        ent.model_id = modelId

        # 城投地位
        if ent.ent_type == "T002":
            ent.position = self.__getPosition__(ent.credit_code)

        # 智象行业CODE
        ent.ccx_industry_code = self.__getCcxIndustryCode__(ent, dcData)

    def __updateFcdbData__(self, ent: EntEnterprise, fcdbData: dict):
        # 企业类型
        if ent.ent_type is None:
            ent.ent_type = self.__convertToEntType__(fcdbData=fcdbData)

        # 企业性质
        nature = self.__convertNatrue(self.__getProperty__(fcdbData, "ORGTYPE"))
        ent.nature = nature

        # 证监会行业一级行业
        ent.srm_trade_type_superior = self.__getProperty__(fcdbData, "SRM_L1_CODE")

        # 证监会行业二级行业
        ent.srm_trade_type = self.__getProperty__(fcdbData, "SRM_L2_CODE")

        # 申万一级行业
        ent.sw_trade_type_superior = self.__getProperty__(fcdbData, "SW_L1_CODE")

        # 申万二级行业
        ent.sw_trade_type = self.__getProperty__(fcdbData, "SW_L2_CODE")

        # 区域
        ent.region_code = self.__fixRegion__(self.__getProperty__(fcdbData, "REGION"))

        # 注册资本
        ent.registered_capital = self.__getProperty__(fcdbData, 'REGCAPITAL')

        # 成立时间
        ent.establishment_date = CommonUtils.strToDate(self.__getProperty__(fcdbData, 'FOUNDDATE'))

        # 注册地址
        ent.registered_address = self.__getProperty__(fcdbData, 'REGADDR')

        # 经营范围
        ent.business_scope = self.__getProperty__(fcdbData, 'BIZSCOPE')

    def __updateShareHolderData__(self, ent: EntEnterprise, shareHolderData: dict):
        # 第一大股东
        ent.share_holder = self.__getProperty__(shareHolderData, "SHCOMPNAME")

        # 占股比例
        ent.share_per = self.__getProperty__(shareHolderData, "PERCENT")

    def __updateActualControllerData__(self, ent: EntEnterprise, actualControllerData: dict):
        # 实际控制人
        ent.enterprise_control = self.__getProperty__(actualControllerData, "ITNAME_P")

    def __updateBankData__(self, ent: EntEnterprise, bankData: dict):
        # 银行区域
        ent.bank_region = self.__getProperty__(bankData, "region_id")

    @staticmethod
    def __fixRegion__(fcdbRegion: str):
        if fcdbRegion is None:
            return None
        if fcdbRegion.startswith("CN"):
            return fcdbRegion[2:]

    # 同步入口
    def update(self, enterpriseList: List[EntEnterprise]):
        self.logger.info("更新主体基础信息 开始")

        # 待更新名单
        self.logger.info("待更新主体：%d" % len(enterpriseList))

        # 加载城投数据
        self.logger.info("加载 数据中心城投数据")
        cityInvestmentDatas = self.__queryCityInvestmentData__()
        self.cityInvestmentDatas = {d["credit_code"]: d for d in cityInvestmentDatas}
        self.logger.info("加载 数据中心城投数据：%d" % len(self.cityInvestmentDatas))

        # 加载区域数据
        self.logger.info("加载 数据中心区域数据")
        regionsData = self.__queryRegions__()
        self.regions = {d["code"]: d for d in regionsData}
        self.logger.info("加载 数据中心区域数据：%d" % len(self.regions))

        # 加载模型-行业映射关系
        self.logger.info("加载 模型-行业映射关系")
        self.modelIndustryMapping = self.__queryModelIndustryMapping__()
        self.logger.info("加载 模型-行业映射关系：%d" % len(self.modelIndustryMapping))

        # 从财汇抽取企业基础数据
        self.logger.info("加载 财汇企业数据")
        fcdbDatas = None
        cacheFile = "__queryFromFcdb__.tmp"
        if self.useCache:
            # 读取缓存
            tmp = CommonUtils.load_dump(cacheFile)
            if tmp is not None:
                self.logger.info("Load cache")
                fcdbDatas = tmp
        if fcdbDatas is None:
            compCodes = list(ent.comp_code for ent in enterpriseList)
            fcdbDatas = BatchUtils.batchQuery(self.__queryFromFcdb__, compCodes, self.size)
            fcdbDatas = {d["COMPCODE"]: d for d in fcdbDatas}
            if self.useCache:
                CommonUtils.save_dump(cacheFile, fcdbDatas)
        self.logger.info("加载 汇企业数据： %d" % len(fcdbDatas))

        for ent in enterpriseList:
            fcdbData = self.__getProperty__(fcdbDatas, ent.comp_code)
            if fcdbData is not None:
                self.__updateFcdbData__(ent, fcdbData)

        # 从财汇抽取股东
        self.logger.info("加载 财汇股东信息")
        shareHolderDatas = None
        cacheFile = "__queryShareholder__.tmp"
        if self.useCache:
            # 读取缓存
            tmp = CommonUtils.load_dump(cacheFile)
            if tmp is not None:
                self.logger.info("Load cache")
                shareHolderDatas = tmp
        if shareHolderDatas is None:
            shareHolderDatas = BatchUtils.batchQuery(self.__queryShareholder__, compCodes, self.size)
            shareHolderDatas = {d["COMPCODE"]: d for d in shareHolderDatas}
            if self.useCache:
                CommonUtils.save_dump(cacheFile, shareHolderDatas)
        self.logger.info("加载 财汇股东信息：%d" % len(shareHolderDatas))

        for ent in enterpriseList:
            shareHolderData = self.__getProperty__(shareHolderDatas, ent.comp_code)
            if shareHolderData is not None:
                self.__updateShareHolderData__(ent, shareHolderData)

        # 从财汇抽取实际控制人
        self.logger.info("加载 财汇实际控制人信息")
        actualControllerDatas = None
        cacheFile = "__queryActualController__.tmp"
        if self.useCache:
            # 读取缓存
            tmp = CommonUtils.load_dump(cacheFile)
            if tmp is not None:
                self.logger.info("Load cache")
                actualControllerDatas = tmp
        if actualControllerDatas is None:
            actualControllerDatas = BatchUtils.batchQuery(self.__queryActualController__, compCodes, self.size)
            actualControllerDatas = {d["SITCode"]: d for d in actualControllerDatas}
            if self.useCache:
                CommonUtils.save_dump(cacheFile, actualControllerDatas)
        self.logger.info("加载 财汇实际控制人信息：%d" % len(actualControllerDatas))

        for ent in enterpriseList:
            actualControllerData = self.__getProperty__(actualControllerDatas, ent.comp_code)
            self.__updateActualControllerData__(ent, actualControllerData)

        # 加载银行数据
        bankDatas = self.__queryBankDatas__()
        self.logger.info("加载 数据中心银行数据")
        bankDatas = {d["credit_code"]: d for d in bankDatas}
        self.logger.info("加载 数据中心银行数据：%d" % len(bankDatas))
        for ent in enterpriseList:
            bankData = self.__getProperty__(bankDatas, ent.credit_code)
            if bankData is not None:
                self.__updateBankData__(ent, bankData)

        # 加载数据中心企业名单
        self.logger.info("加载 数据中心企业数据")
        dcAllEnterprise = self.__queryAllFromDcDb__()
        dcAllEnterprise = {d["credit_code"]: d for d in dcAllEnterprise}
        self.logger.info("加载 数据中心企业数据：%d" % len(dcAllEnterprise))
        for ent in enterpriseList:
            dcData = self.__getProperty__(dcAllEnterprise, ent.credit_code)
            if dcData is not None:
                self.__updateDcData__(ent, dcData)
        del dcAllEnterprise

        # 加载医药二级行业
        self.logger.info("加载 医药二级行业")
        hy015Map = self.__queryHY015Mapping__()
        self.logger.info("加载 农林牧渔二级行业")
        hy012Map = self.__queryHY012Mapping__()
        self.logger.info("加载 祖灵二级行业")
        hy040Map = self.__queryHY040Mapping__()
        self.logger.info("加载 农林牧渔二级行业")
        bankLevelMap = self.__queryBankLevelMapping__()
        hy015Map = {d["credit_code"]: d["value"] for d in hy015Map}
        self.logger.info("加载 医药二级行业：%d" % len(self.hy015Map))
        hy012Map = {d["credit_code"]: d["value"] for d in hy012Map}
        bankLevelMap = {d["code"]: d["level"] for d in bankLevelMap}
        self.logger.info("加载 农林牧渔二级行业：%d" % len(self.hy012Map))
        hy040Map = {d["credit_code"]: d["value"] for d in hy040Map}
        self.logger.info("加载 租赁二级行业：%d" % len(self.hy040Map))

        for ent in enterpriseList:
            if ent.trade_type == "医药":
                ent.model_level = None if ent.credit_code not in hy015Map.keys() else hy015Map.get(ent.credit_code)
            if ent.trade_type == "融资租赁":
                ent.model_level = None if ent.credit_code not in hy040Map.keys() else hy040Map.get(ent.credit_code)
                if (ent.model_level != None and ent.model_level == "1"):
                    ent.model_level = "金融租赁"
                else:
                    ent.model_level = "融资租赁"
            if ent.trade_type == "农林牧渔":
                ent.model_level = None if ent.credit_code not in hy012Map.keys() else hy012Map.get(ent.credit_code)
                if (ent.model_level != None and ent.model_level == "养殖业（饲料、养殖捕捞）"):
                    ent.model_level = "养殖业"
            if ent.ent_type == "T003":
                ent.model_level = None if str(ent.bank_region) not in bankLevelMap.keys() else bankLevelMap.get(str(ent.bank_region))

        self.logger.info("更新主体基础信息 完成")

    def writedb(self, enterpriseList: List[EntEnterprise]):
        self.logger.info("写入数据库 开始")

        # 主体分类缺失的，一律为 T005:其他
        for ent in enterpriseList:
            if ent.ent_type is None:
                ent.ent_type = "T005"

        updateDatas = list(ent.__dict__ for ent in enterpriseList)
        #BatchUtils.batchUpdate(self.__writedb__, updateDatas, self.size)
        #self.logger.info("写入数据库 完成")
